#include "bondquotecdcchart.h"
#include <widgets/chart/basechart_plot.h>
#include <widgets/chart/basechart_graph.h>
#include <core/comdefs.h>
#include <core/Utility.h>
#include <core/time/system_time.h>
#include <core/StyleMgr.h>
#include <widgets/STips.h>

#define CHARTBONDQUOTE_MINSHOW	4.f
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#define max(a,b)            (((a) > (b)) ? (a) : (b))

#pragma warning(disable:4018)
namespace qb
{
	BondQuoteCDCChart::BondQuoteCDCChart(QWidget* parent)
		: QWidget(parent)
		, m_currentTab(0)
		, m_nMarketType(0)
		, m_nHotPoint(-1)
		, m_nDateSel(1)
		, m_nStartDay(0)
		, m_nEndDay(0)
		, m_nBegin(0)
		, m_nEnd(0)
		, m_bOptionBond(false)
		, m_bCDCLocked(false)
		, m_dMinX(0.0)
		, m_dMaxX(0.0)
		, m_dMinY(0.0)
		, m_dMaxY(0.0)
		, m_dOriginMinX(0.0)
		, m_dOriginMaxX(0.0)
		, m_dDragLeft(0.0)
		, m_dDragRight(0.0)
	{
		for (int i = 0; i < 3; i++)
		{
			m_EvaType.push_back(0);
		}
	}

	BondQuoteCDCChart::~BondQuoteCDCChart()
	{
	}

	void BondQuoteCDCChart::setBondInfo(const CBondInfo* bondinfo)
	{
		mBondInfo = (CBondInfo*)bondinfo;
	}

	void BondQuoteCDCChart::setOptionBond(bool bOption)
	{
		m_bOptionBond = bOption;
	}

	void BondQuoteCDCChart::setCheck(int idx, int check)
	{
		if (idx < 0 || idx >= (int)m_EvaType.size())
		{
			return;
		}

		m_EvaType[idx] = check;
	}

	void BondQuoteCDCChart::loadKLineData(xCDCKlineDayList_c* pData)
	{
		inputKLineData(pData);
		refreshData();
	}

	void BondQuoteCDCChart::createChart()
	{
		verticalLayout = new QVBoxLayout(this);
		customPlot = new BaseChartCustomPlot(this);
		verticalLayout->addWidget(customPlot);
		this->setLayout(verticalLayout);

		connect(customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(onMouseMove(QMouseEvent*)));
		connect(customPlot, &BaseChartCustomPlot::mouseDoubleClick, [=]() { emit mouseDoubleClick(this); });

		QBrush boxBrush(StyleMgr::instance().color("BasicPlate"));
		customPlot->setBackground(boxBrush);

		customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
		customPlot->xAxis->grid()->setCustomAxisGrid(this);
		customPlot->yAxis->grid()->setCustomAxisGrid(this);
		customPlot->xAxis->setYAxis(customPlot->yAxis);
		customPlot->yAxis->setTickLabelPadding(40);
		
		customPlot->graph(0)->setLineStyle(BaseChartGraph::lsLine);
		customPlot->graph(0)->setScatterStyle(BaseChartScatterStyle(BaseChartScatterStyle::ssCircle, 3));

		customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
		customPlot->graph(1)->setLineStyle(BaseChartGraph::lsLine);
		customPlot->graph(1)->setScatterStyle(BaseChartScatterStyle(BaseChartScatterStyle::ssCircle, 3));

		customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
		customPlot->graph(2)->setLineStyle(BaseChartGraph::lsLine);
		customPlot->graph(2)->setScatterStyle(BaseChartScatterStyle(BaseChartScatterStyle::ssCircle, 3));

		customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
		customPlot->graph(3)->setLineStyle(BaseChartGraph::lsLine);
		customPlot->graph(3)->setScatterStyle(BaseChartScatterStyle(BaseChartScatterStyle::ssCircle, 3));

		customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
		customPlot->graph(4)->setLineStyle(BaseChartGraph::lsLine);
		customPlot->graph(4)->setScatterStyle(BaseChartScatterStyle(BaseChartScatterStyle::ssCircle, 3));

		customPlot->xAxis->setCustomGrid();
		customPlot->yAxis->setCustomGrid();
		customPlot->xAxis->setSubTicks(false);
		customPlot->yAxis->setSubTicks(false);
		customPlot->yAxis->ticker()->setTickCount(4);

		QString qText = tr("估值收益率");
		bcte = new BaseChartTextElement(customPlot, qText, QFont("Microsoft YaHei", 9, QFont::Bold));
		bcte->setCustomDraw(this);
		bcte->setTextFlags(Qt::AlignLeft | Qt::AlignVCenter);
		bcte->setTextOffset(18);
		bcte->setTextColor(StyleMgr::instance().color("TextNormal"));
		customPlot->plotLayout()->addElement(1, 0, bcte);

		bcde = new BaseChartDragBarElement(customPlot);
		customPlot->plotLayout()->addElement(2, 0, bcde);

		refreshData();
	}

	void BondQuoteCDCChart::setTab(int tab)
	{
		m_currentTab = tab;
	}

	void BondQuoteCDCChart::setMarketType(em_BrokerKinds emCurType)
	{
		if (emCurType == em_Exchange)
			m_nMarketType = 2;
		else if (emCurType == em_CFETS)
			m_nMarketType = 1;
		else
			m_nMarketType = 0;
	}

	void BondQuoteCDCChart::setDateSel(int nIndex)
	{
		m_nDateSel = nIndex;
		m_dDragLeft = 0.0;
		m_dDragRight = 0.0;
		m_nBegin = 0;
		m_nEnd = 0;
		m_nStartDay = 0;
		m_nEndDay = 0;
		m_dOriginMinX = 0.0;
		m_dOriginMaxX = 0.0;
	}

	int BondQuoteCDCChart::getDateSel(int nIndex)
	{
		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (!pDataKLine || pDataKLine->m_List.size() <= 0) {
			return 0;
		}

		int i = 0;
		switch (nIndex) {
		case 0: {
			std::list<PriceKLine>::reverse_iterator it = pDataKLine->m_List.rbegin();
			UINT date = it->m_Date;
			if ((date % 10000) / 100 > 1) {
				date = date - 100;
			}
			else {
				date = (date / 10000 - 1) * 10000 + 1200 + (date % 100);
			}
			i = pDataKLine->m_List.size() - 1;
			for (; it != pDataKLine->m_List.rend(); it++, i--) {
				if (it->m_Date <= date) {
					i++;
					break;
				}
			}
			break;
		}
		case 1: {
			std::list<PriceKLine>::reverse_iterator it = pDataKLine->m_List.rbegin();
			UINT date = it->m_Date;
			if ((date % 10000) / 100 > 3) {
				date = date - 300;
			}
			else {
				date = (date / 10000 - 1) * 10000 + (((date % 10000) / 100) + 9) * 100 + (date % 100);
			}
			i = pDataKLine->m_List.size() - 1;
			for (; it != pDataKLine->m_List.rend(); it++, i--) {
				if (it->m_Date <= date) {
					i++;
					break;
				}
			}
			break;
		}
		case 2: {
			std::list<PriceKLine>::reverse_iterator it = pDataKLine->m_List.rbegin();
			UINT date = it->m_Date;
			if ((date % 10000) / 100 > 6) {
				date = date - 600;
			}
			else {
				date = (date / 10000 - 1) * 10000 + (((date % 10000) / 100) + 6) * 100 + (date % 100);
			}
			i = pDataKLine->m_List.size() - 1;
			for (; it != pDataKLine->m_List.rend(); it++, i--) {
				if (it->m_Date <= date) {
					i++;
					break;
				}
			}
			break;
		}
		case 3: {
			std::list<PriceKLine>::reverse_iterator it = pDataKLine->m_List.rbegin();
			UINT date = it->m_Date / 10000;
			i = pDataKLine->m_List.size() - 1;
			for (; it != pDataKLine->m_List.rend(); it++, i--) {
				if (date != it->m_Date / 10000) {
					i++;
					break;
				}
			}
			break;
		}
		case 4: {
			std::list<PriceKLine>::reverse_iterator it = pDataKLine->m_List.rbegin();
			UINT date = it->m_Date;
			i = pDataKLine->m_List.size() - 1;
			for (; it != pDataKLine->m_List.rend(); it++, i--) {
				UINT dd = date - it->m_Date;
				if (date - it->m_Date >= 10000) {
					i++;
					break;
				}
			}
			break;
		}
		case 5: {
			break;
		}
		default:
			return 0;
		}

		i = min((int)pDataKLine->m_List.size() - 5, i);
		i = max(0, i);

		return i;
	}

	void BondQuoteCDCChart::setCalendar(int startDay, int endDay)
	{
		if (isValidCalendar(startDay, endDay))
		{
			m_nStartDay = startDay;
			m_nEndDay = endDay;
		}

		emit calendarChanged(startDay, endDay);
	}

	bool BondQuoteCDCChart::getCalendarSel(int& nBegin, int& nEnd)
	{
		if (m_nStartDay == 0 || m_nStartDay >= m_nEndDay)
		{
			return false;
		}

		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (!pDataKLine || pDataKLine->m_List.size() <= 0) {
			return false;
		}

		nBegin = 0;
		int i = 0;
		std::list<PriceKLine>::iterator it;
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++)
		{
			if (it->m_Date <= m_nStartDay)
				nBegin = i;
			else
				break;
		}

		nEnd = 0;
		i = 0;
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++) {
			if (it->m_Date > m_nEndDay)
				break;
			nEnd = i;
		}

		nBegin = max(nBegin, 0);
		nEnd = min(nEnd + 1, pDataKLine->m_List.size() - 1);

		return true;
	}

	bool BondQuoteCDCChart::isValidCalendar(int& nStartDay, int& nEndDay)
	{
		if (nStartDay == 0 || nStartDay >= nEndDay)
		{
			nStartDay = 0;
			nEndDay = 0;
			return false;
		}

		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (!pDataKLine || pDataKLine->m_List.size() <= 0) {
			nStartDay = 0;
			nEndDay = 0;
			return false;
		}

		int nBegin = 0;
		int i = 0;
		std::list<PriceKLine>::iterator it;
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++)
		{
			if (it->m_Date <= nStartDay)
				nBegin = i;
			else
				break;
		}

		int nEnd = 0;
		i = 0;
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++) {
			if (it->m_Date > nEndDay)
				break;
			nEnd = i;
		}

		nBegin = max(nBegin, 0);
		nEnd = min(nEnd + 1, pDataKLine->m_List.size() - 1);

		if (nEnd - nBegin <= 5)
		{
			nStartDay = pDataKLine->m_List.front().m_Date;
			nEndDay = pDataKLine->m_List.back().m_Date;
			return false;
		}

		return true;
	}

	void BondQuoteCDCChart::setLeftDrag(double ratio)
	{
		QB_CHECK_RETURN_VOID1(customPlot);

		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (!pDataKLine || pDataKLine->m_List.size() <= 0) {
			return;
		}

		double dBegin = ratio * (m_dOriginMaxX - m_dOriginMinX);
		int nBegin = (int)dBegin;
		m_dDragLeft = max(dBegin, m_dOriginMinX + 0.1);
		m_nBegin = max(nBegin, m_dOriginMinX);
	}

	void BondQuoteCDCChart::setRightDrag(double ratio)
	{
		QB_CHECK_RETURN_VOID1(customPlot);

		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (!pDataKLine || pDataKLine->m_List.size() <= 0) {
			return;
		}

		double dEnd = ratio * (m_dOriginMaxX - m_dOriginMinX);
		int nEnd = (int)dEnd;
		m_dDragRight = min(dEnd, m_dOriginMaxX);
		m_nEnd = min(nEnd + 1, m_dOriginMaxX);
	}

	void BondQuoteCDCChart::setCentralDrag(double ratio1, double ratio2)
	{
		setLeftDrag(ratio1);
		setRightDrag(ratio2);
	}

	PriceKLineList* BondQuoteCDCChart::GetPriceKLineList()
	{
		PriceKLineList* pList = &m_DataKLineBroker;
		if (m_nMarketType == 1)pList = &m_DataKLineCFETS;
		else if (m_nMarketType == 2)pList = &m_DataKLineExchange;
		return pList;
	}

	bool BondQuoteCDCChart::drawGridXLines(BaseChartPainter* painter)
	{
		drawMouseMoveLine(painter);

		PriceKLineList* pDataKLine = GetPriceKLineList();

		int count = 0;
		int firstindex = -1, lastindex = -1;
		for (int i = 0; i <= m_dMaxX; i++) {
			if (i >= m_dMinX && i <= m_dMaxX) {
				if (firstindex < 0)firstindex = i;
				lastindex = i;
				count++;
			}
		}
		if (firstindex < 0 || count <= 0)return true;
		int dx = max(1, (int)(((float)count) / CHARTBONDQUOTE_MINSHOW + 0.4));
		int top = customPlot->yAxis->axisRect()->top();
		int bottom = customPlot->yAxis->axisRect()->bottom();

		int nFlag = Qt::TextDontClip | Qt::AlignCenter | Qt::AlignVCenter;
		QRectF rect(0, 0, 10000, 10000);

		std::list<PriceKLine>::iterator it;
		int n = GetKLineIndex(lastindex, it);
		if (n < 0)return true;
		int X, LX;
		QString szText;
		QFont font("Microsoft YaHei");
		font.setPixelSize(12);
		painter->setFont(font);

		if (n == lastindex)
		{
			szText = GetKLineDateString(it);
			X = customPlot->xAxis->coordToPixel(lastindex);
			painter->drawLine(QLineF(X, bottom, X, top));

			QRectF measureRect = painter->boundingRect(rect, nFlag, szText);
			QPen oldPen = painter->pen();
			painter->setPen(QColor(128, 128, 128, 255));
			LX = min(customPlot->xAxis->axisRect()->right() - measureRect.width(), X - measureRect.width() / 2);
			painter->drawText(LX, bottom, measureRect.width(), measureRect.height(), nFlag, szText);
			painter->setPen(oldPen);
		}
		else
		{
			LX = customPlot->xAxis->axisRect()->right();
		}
		int nXEnd = -1;
		for (n = firstindex; n < lastindex; n += dx)
		{
			if (GetKLineIndex(n, it) != n)continue;
			szText = GetKLineDateString(it);
			X = customPlot->xAxis->coordToPixel(n);

			QRectF measureRect = painter->boundingRect(rect, nFlag, szText);
			if ((X + measureRect.width() / 2) >= LX)continue;
			if (X < nXEnd) continue;
			nXEnd = X + measureRect.width();
			painter->drawLine(QLineF(X, bottom, X, top));
			int i = 0;

			QPen oldPen = painter->pen();
			painter->setPen(QColor(128, 128, 128, 255));

			for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++) {
				if (i == n) {
					szText = strInt2DateInTable(it->m_Date);
					QRectF measureRect = painter->boundingRect(rect, nFlag, szText);
					if (n == lastindex)
						if (X + measureRect.width() / 2 > customPlot->xAxis->axisRect()->right())
							painter->drawText(customPlot->xAxis->axisRect()->right() - measureRect.width(), bottom, measureRect.width(), measureRect.height(), nFlag, szText);
						else
							painter->drawText(X - measureRect.width() / 2, bottom, measureRect.width(), measureRect.height(), nFlag, szText);
					else
						painter->drawText(X - measureRect.width() / 2, bottom, measureRect.width(), measureRect.height(), nFlag, szText);

					break;
				}
			}

			painter->setPen(oldPen);
		}

		return true;
	}

	bool BondQuoteCDCChart::drawGridYLines(BaseChartPainter* painter)
	{
		QString szValue;
		QRectF rfText;
		int nTextTop = 10000;//纵轴刻度文字
		int top = customPlot->yAxis->axisRect()->top();
		int bottom = customPlot->yAxis->axisRect()->bottom();
		int tickCount = (customPlot->yAxis->ticker()->tickCount() == 0 ? 4 : customPlot->yAxis->ticker()->tickCount());
		double step = (m_dMaxY - m_dMinY) / tickCount;
		QRectF rect(0, 0, 10000, 10000);
		int nFlag = Qt::TextDontClip | Qt::AlignLeft | Qt::AlignVCenter;
		int i = 0;

		while (1) {
			float price = m_dMinY + step * i;
			int Y = customPlot->yAxis->coordToPixel(price);
			if (Y < top - 1 || Y > bottom)break;
			if (Y <= bottom) 
			{
				painter->drawLine(QLineF(customPlot->xAxis->axisRect()->left() - customPlot->yAxis->tickLabelPadding(), Y, customPlot->xAxis->axisRect()->right(), Y));
				if (((int)(step * 100)) % 10 > 0 || ((int)(m_dMinY * 100)) % 10 > 0 || ((int)(m_dMaxY * 100)) % 10 > 0) szValue = QString("%1").arg(price, 0, 'f', 2, '0');
				else szValue = QString("%1").arg(price, 0, 'f', 1, '0');
				QRectF measureRect = painter->boundingRect(rect, nFlag, szValue);
				QPen oldPen = painter->pen();
				painter->setPen(QColor(128, 128, 128, 255));
				painter->drawText(customPlot->xAxis->axisRect()->left() - customPlot->yAxis->tickLabelPadding() + 2, Y - measureRect.height(), measureRect.width(), measureRect.height(), nFlag, szValue);
				painter->setPen(oldPen);
			}
			i++;
			if (i > 100)
				break;
		}

		painter->drawLine(QLineF(customPlot->xAxis->axisRect()->left() - customPlot->yAxis->tickLabelPadding(), top, customPlot->xAxis->axisRect()->right(), top));

		return true;
	}

	void BondQuoteCDCChart::drawMouseMoveLine(BaseChartPainter* painter)
	{
		QB_CHECK_RETURN_VOID1(customPlot);

		int x = mapFromGlobal(QCursor().pos()).x() - 8;
		int y = mapFromGlobal(QCursor().pos()).y() - 8;
		int top = customPlot->yAxis->axisRect()->top();
		int bottom = customPlot->yAxis->axisRect()->bottom();
		int left = customPlot->yAxis->axisRect()->left();
		int right = customPlot->yAxis->axisRect()->right();

		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (pDataKLine && pDataKLine->m_List.size() > 1)
		{
			right = min((int)customPlot->xAxis->coordToPixel(min((int)m_dMaxX, (int)(pDataKLine->m_List.size() - 1))), right);
		}
		else
		{
			right = left;
		}

		if (x < left || x > right || y < top || y > bottom)
		{
			return;
		}

		painter->drawLine(QLineF(x, bottom, x, top));
	}

	bool BondQuoteCDCChart::customDraw(BaseChartPainter* painter, const QRect& rect)
	{//下标text底色
		if (m_currentTab == 0)
		{
			if (m_bOptionBond)
			{
				if (m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					QColor clr[2];
					clr[0] = QColor(251, 194, 69); //行权收益率
					clr[1] = QColor(0, 89, 255);   //到期收益率
					customDraw(painter, rect, 2, clr);
				}
				else if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{
					QColor clr[1];
					clr[0] = QColor(124, 84, 195); //成交
					customDraw(painter, rect, 1, clr);
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] == 1)
				{
					QColor clr[3];
					clr[0] = QColor(251, 194, 69);
					clr[1] = QColor(0, 89, 255);
					clr[2] = QColor(124, 84, 195); //成交
					customDraw(painter, rect, 3, clr);
				}
			/*	else if (m_EvaType[1] == 0 && m_EvaType[2] == 1)
				{
					QColor clr[4];
					clr[0] = QColor(251, 194, 69);
					clr[1] = QColor(0, 89, 255);
					clr[2] = QColor(255, 125, 0);
					clr[3] = QColor(0, 154, 255);
					customDraw(painter, rect, 4, clr);
				}
				else if (m_EvaType[1] == 1 && m_EvaType[2] == 1)
				{
					QColor clr[5];
					clr[0] = QColor(251, 194, 69);
					clr[1] = QColor(0, 89, 255);
					clr[2] = QColor(255, 125, 0);
					clr[3] = QColor(124, 84, 195);
					clr[4] = QColor(0, 154, 255);
					customDraw(painter, rect, 5, clr);
				}*/
			}
			else
			{
				if (m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					QColor clr[1];
					clr[0] = QColor(205, 119, 4);//估值收益率
					customDraw(painter, rect, 1, clr);
				}
				else if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{
					QColor clr[1];
					clr[0] = QColor(124, 84, 195);//成交
					customDraw(painter, rect, 1, clr);
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] == 1)
				{
					QColor clr[2];
					clr[0] = QColor(205, 119, 4);//估值
					clr[1] = QColor(124, 84, 195);//成交
					customDraw(painter, rect, 2, clr);
				}
				/*		else if (m_EvaType[1] == 0 && m_EvaType[2] == 1)
						{
							QColor clr[3];
							clr[0] = QColor(205, 119, 4);
							clr[1] = QColor(255, 125, 0);
							clr[2] = QColor(0, 154, 255);
							customDraw(painter, rect, 3, clr);
						}
						else if (m_EvaType[1] == 1 && m_EvaType[2] == 1)
						{
							QColor clr[4];
							clr[0] = QColor(205, 119, 4);
							clr[1] = QColor(255, 125, 0);
							clr[2] = QColor(0, 154, 255);
							clr[3] = QColor(124, 84, 195);
							customDraw(painter, rect, 4, clr);
						}*/
			}
		}
		else if (m_currentTab == 1)
		{
			if (m_bOptionBond)
			{
				QColor clr[1];
				clr[0] = QColor(124, 84, 195);//成交
				customDraw(painter, rect, 1, clr);
			}
			else
			{
				if (m_EvaType[0] == 1 && m_EvaType[1] == 1)
				{
					QColor clr[2];
					clr[0] = QColor(205, 119, 4); //估值
					clr[1] = QColor(124, 84, 195); //成交
					customDraw(painter, rect, 2, clr);
				}
				else if(m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					QColor clr[1];
					clr[0] = QColor(205, 119, 4);
					customDraw(painter, rect, 1, clr);
				}
				else if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{
					QColor clr[1];
					clr[0] = QColor(124, 84, 195);
					customDraw(painter, rect, 1, clr);
				}
			}
		}

		return true;
	}

	void BondQuoteCDCChart::customDraw(BaseChartPainter* painter, const QRect& rect, int count, QColor* clr)
	{
		QRect rectBK = rect;

		for (int i = 0; i < count; i++)
		{
			if (i == 0)
			{
				rectBK.setLeft(rect.left());
			}
			else
			{
				rectBK.setLeft(rect.left() + i * rect.width() / count + 2);
			}

			if (i == count - 1)
			{
				rectBK.setRight(rect.right());
			}
			else
			{
				rectBK.setRight(rectBK.left() + rect.width() / count - 2);
			}
			
			painter->fillRect(rectBK, QColor(38, 55, 53));
			painter->setPen(clr[i]);
			painter->drawLine(QLineF(rect.left() + rect.width() / count * i + 6, rect.top() + rect.height() / 2, rect.left() + rect.width() / count * i + 14, rect.top() + rect.height() / 2));
			painter->drawLine(QLineF(rect.left() + rect.width() / count * i + 6, rect.top() + rect.height() / 2 + 1, rect.left() + rect.width() / count * i + 14, rect.top() + rect.height() / 2 + 1));
		}
	}

	void BondQuoteCDCChart::inputKLineData(xCDCKlineDayList_c* pData)
	{
		PriceKLineList* pDataKLine = GetPriceKLineList();
		pDataKLine->Clear();

		xCDCKlineDayList_c* pKLine = (xCDCKlineDayList_c*)pData;
		if (!pKLine || pKLine->m_List.size() <= 0) {
			return;
		}

		std::list<xCDCKlineDayUnit_c>::iterator it;
		PriceKLine item;

		for (it = pKLine->m_List.begin(); it != pKLine->m_List.end(); ++it) {
			if (m_currentTab == 0)
			{
				item.m_Price1 = it->m_ValueYield;
				if (m_bOptionBond)
				{
					item.m_Price2 = it->m_CleanPrice; //含权债的到期收益率
				}

				if (m_EvaType[1] == 1)
				{
					item.m_Price4 = it->m_DealYield;
				}
				if (m_EvaType[2] == 1)
				{
					if (!m_bOptionBond)
					{
						item.m_Price2 = it->m_QuoteBid;
						item.m_Price3 = it->m_QuoteOfr;
					}
					else if (m_bOptionBond)
					{
						item.m_Price3 = it->m_QuoteBid;
						item.m_Price5 = it->m_QuoteOfr;
					}
				}

				if (item.m_Price1 <= 0 && item.m_Price2 <= 0 && item.m_Price3 <= 0 && item.m_Price4 <= 0 && item.m_Price5 <= 0)
					continue;
			}
			else if (m_currentTab == 1)
			{
				if (m_EvaType[1] == 1)
				{
					item.m_Price4 = it->m_DealClean;
				}
				if (!m_bOptionBond)
				{
					item.m_Price2 = it->m_CleanPrice;	//估值净价
				}

				if (item.m_Price2 <= 0 && item.m_Price4 <= 0)
					continue;
			}
			item.m_Date = it->m_Date;
			pDataKLine->Insert(item);
		}

		pDataKLine->m_List.sort();

		if (pDataKLine->m_List.size() < 6)
		{
			bcde->setEnable(false);
		}
		else
		{
			bcde->setEnable(true);
		}

		m_dOriginMaxX = max(m_dOriginMaxX, pDataKLine->m_List.size() - 1);
		m_dOriginMaxX = min(m_dOriginMaxX, pDataKLine->m_List.size() - 1);

		if (m_dDragLeft == 0.0 && m_dDragRight == 0.0)
		{
			if (!getCalendarSel(m_nBegin, m_nEnd))
			{
				m_nBegin = getDateSel(m_nDateSel);
			}
		}

		if (m_nBegin > 0 && !pDataKLine->m_List.empty() && m_nBegin < pDataKLine->m_List.size() - 1)
		{
			auto itBegin = pDataKLine->m_List.begin();
			auto itEnd = pDataKLine->m_List.begin();
			std::advance(itEnd, m_nBegin);
			pDataKLine->m_List.erase(itBegin, itEnd);
		}
		if (m_nEnd - m_nBegin > 0 && !pDataKLine->m_List.empty() && m_nEnd - m_nBegin < pDataKLine->m_List.size() - 1)
		{
			auto itBegin = pDataKLine->m_List.begin();
			auto itEnd = pDataKLine->m_List.end();
			std::advance(itBegin, m_nEnd - m_nBegin);
			pDataKLine->m_List.erase(itBegin, itEnd);
		}

		if (pDataKLine->m_List.size() > 0)
		{
			emit calendarChanged(pDataKLine->m_List.front().m_Date, pDataKLine->m_List.back().m_Date);
		}
		else
		{
			emit calendarChanged(0, 0);
		}
	}

	void BondQuoteCDCChart::refreshData()
	{
		QB_CHECK_RETURN_VOID1(customPlot && customPlot->graph(0) && bcte && bcde);

		PriceKLineList* pDataKLine = GetPriceKLineList();

		QVector<double>	vctX0, vctY0;
		QVector<double>	vctX1, vctY1;
		QVector<double>	vctX2, vctY2;
		QVector<double>	vctX3, vctY3;
		QVector<double>	vctX4, vctY4;

		m_dMinX = 0;
		m_dMaxX = CHARTBONDQUOTE_MINSHOW;
		if (pDataKLine->m_List.size() > 0)m_dMaxX = max(m_dMaxX, pDataKLine->m_List.size() - 1);

		int i = 0;
		std::list<PriceKLine>::iterator it;
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); ++it, i++)
		{
			if (m_currentTab == 0)
			{
				if ((*it).m_Price1 > 0)
				{
					vctY0.push_back((*it).m_Price1);
					vctX0.push_back(i);
				}
				if ((*it).m_Price2 > 0)
				{
					vctY1.push_back((*it).m_Price2);
					vctX1.push_back(i);
				}
				if ((*it).m_Price3 > 0)
				{
					vctY2.push_back((*it).m_Price3);
					vctX2.push_back(i);
				}
				if ((*it).m_Price4 > 0)
				{
					vctY3.push_back((*it).m_Price4);
					vctX3.push_back(i);
				}
				if ((*it).m_Price5 > 0)
				{
					vctY4.push_back((*it).m_Price5);
					vctX4.push_back(i);
				}
			}
			else if (m_currentTab == 1)
			{
				if ((*it).m_Price2 > 0)
				{
					vctY0.push_back((*it).m_Price2);
					vctX0.push_back(i);
				}
				if ((*it).m_Price4 > 0)
				{
					vctY1.push_back((*it).m_Price4);
					vctX1.push_back(i);
				}
			}
		}

		//m_EvaType:0:估值原先是默认选择的，现在是comobox选择
		//m_EvaType:1:成交
		//m_EvaType:2:报价

		if (m_currentTab == 0)
		{//收益率
			if (m_EvaType[0] == 1)
			{//到期收益率&行权收益率
				customPlot->graph(0)->setVisible(true);//估值
				customPlot->graph(0)->setData(vctX0, vctY0);
			}
			else
			{
				customPlot->graph(0)->setVisible(false);
			}

			//成交
			if (m_EvaType[1] == 1)
			{
				customPlot->graph(3)->setVisible(true);//成交
				customPlot->graph(3)->setData(vctX3, vctY3);
			}
			else
			{
				customPlot->graph(3)->setVisible(false);
			}


			if (m_bOptionBond)
			{ 
				//估值
				if (m_EvaType[0] == 1)
				{//到期收益率&行权收益率
					customPlot->graph(1)->setVisible(true);
					customPlot->graph(1)->setData(vctX1, vctY1);
				}
				else
				{
					customPlot->graph(1)->setVisible(false);
				}
			/*	if (m_EvaType[2] == 1)
				{//报价
					customPlot->graph(2)->setVisible(true);
					customPlot->graph(2)->setData(vctX2, vctY2);
					customPlot->graph(4)->setVisible(true);
					customPlot->graph(4)->setData(vctX4, vctY4);
				}
				else
				{
					customPlot->graph(2)->setVisible(false);
					customPlot->graph(4)->setVisible(false);
				}*/

				customPlot->graph(0)->setPen(QPen(QColor(251, 194, 69))); //行权收益率
				customPlot->graph(1)->setPen(QPen(QColor(0, 89, 255)));   //到期收益率
				customPlot->graph(2)->setPen(QPen(QColor(255, 125, 0)));
				customPlot->graph(3)->setPen(QPen(QColor(124, 84, 195))); //成交
				customPlot->graph(4)->setPen(QPen(QColor(0, 154, 255)));

				//if (m_EvaType[1] == 0 && m_EvaType[2] == 0)
				//{	//原逻辑：成交与报价都未勾选，行权债默认在收益率:行权收益率&到期收益率
				//	bcte->setText(tr("行权收益率"), tr("到期收益率"));
				//}
				//else if (m_EvaType[1] == 1 && m_EvaType[2] == 0)
				//{
				//	bcte->setText(tr("行权收益率"), tr("到期收益率"), tr("成交日线"));
				//}
				//else if (m_EvaType[1] == 0 && m_EvaType[2] == 1)
				//{
				//	bcte->setText(tr("行权收益率"), tr("到期收益率"), tr("bid收盘"), tr("ofr收盘"));
				//}
				//else if (m_EvaType[1] == 1 && m_EvaType[2] == 1)
				//{
				//	bcte->setText(tr("行权收益率"), tr("到期收益率"), tr("bid收盘"), tr("成交日线"), tr("ofr收盘"));
				//}

				if (m_EvaType[0] == 1 && m_EvaType[1] == 1)
				{	//现逻辑：默认打开选择 估值与成交
					bcte->setText(tr("行权收益率"), tr("到期收益率"), tr("成交日线"));
				}
				else if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{//必须选择其一
					bcte->setText(tr("成交日线"));
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					bcte->setText(tr("行权收益率"), tr("到期收益率"));
				}
			}
			else
			{
				/*if (m_EvaType[2] == 1)
				{
					customPlot->graph(1)->setVisible(true);
					customPlot->graph(1)->setData(vctX1, vctY1);
					customPlot->graph(2)->setVisible(true);
					customPlot->graph(2)->setData(vctX2, vctY2);
				}
				else
				{
					customPlot->graph(1)->setVisible(false);
					customPlot->graph(2)->setVisible(false);
				}*/
				customPlot->graph(4)->setVisible(false);

				customPlot->graph(0)->setPen(QPen(QColor(205, 119, 4))); //土黄色
				customPlot->graph(1)->setPen(QPen(QColor(255, 125, 0))); //橙黄
				customPlot->graph(2)->setPen(QPen(QColor(0, 154, 255)));
				customPlot->graph(3)->setPen(QPen(QColor(124, 84, 195)));

				/*if (m_EvaType[1] == 0 && m_EvaType[2] == 0)
				{
					bcte->setText(tr("估值收益率"));
				}
				else if (m_EvaType[1] == 1 && m_EvaType[2] == 0)
				{
					bcte->setText(tr("估值收益率"), tr("成交日线"));
				}
				else if (m_EvaType[1] == 0 && m_EvaType[2] == 1)
				{
					bcte->setText(tr("估值收益率"), tr("bid收盘"), tr("ofr收盘"));
				}
				else if (m_EvaType[1] == 1 && m_EvaType[2] == 1)
				{
					bcte->setText(tr("估值收益率"), tr("bid收盘"), tr("ofr收盘"), tr("成交日线"));
				}*/

				if (m_EvaType[0] == 1 && m_EvaType[1] == 1)
				{
					bcte->setText(tr("估值收益率"), tr("成交日线"));
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					bcte->setText(tr("估值收益率"));
				}
				else if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{
					bcte->setText(tr("成交日线"));
				}
			}
		}
		else if (m_currentTab == 1)
		{//净价
			//行权债 只有 成交
			//非     根据选项判断是估值 or 成交
			customPlot->graph(0)->setData(vctX0, vctY0);
			customPlot->graph(1)->setData(vctX1, vctY1);

			if (m_bOptionBond)
			{
				customPlot->graph(1)->setVisible(true); //成交
				customPlot->graph(0)->setVisible(false); //估值
				bcte->setText(tr("成交日线"));
			}
			else
			{
				if (m_EvaType[0] == 0 && m_EvaType[1] == 1)
				{
					customPlot->graph(1)->setVisible(true); //成交
					customPlot->graph(0)->setVisible(false); //估值
					bcte->setText(tr("成交日线"));
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] == 0)
				{
					customPlot->graph(1)->setVisible(false); //成交
					customPlot->graph(0)->setVisible(true); //估值
					bcte->setText(tr("估值收益率"));
				}
				else if (m_EvaType[0] == 1 && m_EvaType[1] ==1)
				{
					customPlot->graph(1)->setVisible(true); //成交
					customPlot->graph(0)->setVisible(true); //估值
					bcte->setText(tr("估值收益率"), tr("成交日线"));
				}
			}
			customPlot->graph(2)->setVisible(false);
			customPlot->graph(3)->setVisible(false);
			customPlot->graph(4)->setVisible(false);

			customPlot->graph(0)->setPen(QPen(QColor(205, 119, 4)));
			customPlot->graph(1)->setPen(QPen(QColor(124, 84, 195)));
		}
		
		GetShowLimit(m_dMinX, m_dMaxX);
		double dExt = (m_dMaxX - m_dMinX) / 20;
		customPlot->yAxis->setRange(m_dMinY, m_dMaxY);
		customPlot->xAxis->setRange(m_dMinX, m_dMaxX+ dExt);

		if (pDataKLine->m_List.size() > 0 && m_dDragLeft == 0.0 && m_dDragRight == 0.0)
		{
			int end = m_nEnd;
			if (m_nEnd == 0)
			{
				end = m_dOriginMaxX;
			}

			bcde->setPos(getXPos_Value(m_nBegin), getXPos_Value(end));
		}

		customPlot->replot(BaseChartCustomPlot::rpQueuedReplot);
	}

	void BondQuoteCDCChart::GetShowLimit(double fMinXShow, double fMaxXShow) 
	{
		PriceKLineList* pDataKLine = GetPriceKLineList();
		if (pDataKLine->m_List.size() <= 0) {
			m_dMinY = min_show_def;
			m_dMaxY  = max_show_def;
			return;
		}
		m_dMinY = 1000;
		m_dMaxY = -1000;

		bool bBegin = true;
		std::list<PriceKLine>::iterator it;
		std::list<PriceKLine>::iterator itLast1 = pDataKLine->m_List.end();
		std::list<PriceKLine>::iterator itLast2 = pDataKLine->m_List.end();
		std::list<PriceKLine>::iterator itLast3 = pDataKLine->m_List.end();
		std::list<PriceKLine>::iterator itLast4 = pDataKLine->m_List.end();
		std::list<PriceKLine>::iterator itLast5 = pDataKLine->m_List.end();
		int lastitinwork1 = -1;
		int lastitinwork2 = -1;
		int lastitinwork3 = -1;
		int lastitinwork4 = -1;
		int lastitinwork5 = -1;
		int i = 0;
		bool bEnd1 = false;
		bool bEnd2 = false;
		bool bEnd3 = false;
		bool bEnd4 = false;
		bool bEnd5 = false;

		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); ++it, i++) {
			if (i < fMinXShow) {
				if (it->m_Price1 > 0) {
					itLast1 = it;
					lastitinwork1 = i;
				}
				if (it->m_Price2 > 0) {
					itLast2 = it;
					lastitinwork2 = i;
				}
				if (it->m_Price3 > 0) {
					itLast3 = it;
					lastitinwork3 = i;
				}
				if (it->m_Price4 > 0) {
					itLast4 = it;
					lastitinwork4 = i;
				}
				if (it->m_Price5 > 0) {
					itLast5 = it;
					lastitinwork5 = i;
				}
			}
			else {
				if (i <= fMaxXShow) {
					if (it->m_Price1 > 0) {
						if (itLast1 == pDataKLine->m_List.end()) {//first point
							m_dMinY = min(m_dMinY, it->m_Price1);
							m_dMaxY = max(m_dMaxY, it->m_Price1);
						}
						else {
							if (lastitinwork1 < fMinXShow) {
								double fp = (fMinXShow - lastitinwork1) * (it->m_Price1 - itLast1->m_Price1) / (i - lastitinwork1) + itLast1->m_Price1;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							m_dMinY = min(m_dMinY, it->m_Price1);
							m_dMaxY = max(m_dMaxY, it->m_Price1);
						}
						itLast1 = it;
						lastitinwork1 = i;
					}
					if (it->m_Price2 > 0) {
						if (itLast2 == pDataKLine->m_List.end()) {//first point
							m_dMinY = min(m_dMinY, it->m_Price2);
							m_dMaxY = max(m_dMaxY, it->m_Price2);
						}
						else {
							if (lastitinwork2 < fMinXShow) {
								double fp = (fMinXShow - lastitinwork2) * (it->m_Price2 - itLast2->m_Price2) / (i - lastitinwork2) + itLast2->m_Price2;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							m_dMinY = min(m_dMinY, it->m_Price2);
							m_dMaxY = max(m_dMaxY, it->m_Price2);
						}
						itLast2 = it;
						lastitinwork2 = i;
					}
					if (it->m_Price3 > 0) {
						if (itLast3 == pDataKLine->m_List.end()) {//first point
							m_dMinY = min(m_dMinY, it->m_Price3);
							m_dMaxY = max(m_dMaxY, it->m_Price3);
						}
						else {
							if (lastitinwork1 < fMinXShow) {
								double fp = (fMinXShow - lastitinwork1) * (it->m_Price3 - itLast3->m_Price3) / (i - lastitinwork1) + itLast3->m_Price3;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							m_dMinY = min(m_dMinY, it->m_Price3);
							m_dMaxY = max(m_dMaxY, it->m_Price3);
						}
						itLast3 = it;
						lastitinwork3 = i;
					}
					if (it->m_Price4 > 0) {
						if (itLast4 == pDataKLine->m_List.end()) {//first point
							m_dMinY = min(m_dMinY, it->m_Price4);
							m_dMaxY = max(m_dMaxY, it->m_Price4);
						}
						else {
							if (lastitinwork4 < fMinXShow) {
								double fp = (fMinXShow - lastitinwork4) * (it->m_Price4 - itLast4->m_Price4) / (i - lastitinwork4) + itLast4->m_Price4;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							m_dMinY = min(m_dMinY, it->m_Price4);
							m_dMaxY = max(m_dMaxY, it->m_Price4);
						}
						itLast4 = it;
						lastitinwork4 = i;
					}
					if (it->m_Price5 > 0) {
						if (itLast5 == pDataKLine->m_List.end()) {//first point
							m_dMinY = min(m_dMinY, it->m_Price5);
							m_dMaxY = max(m_dMaxY, it->m_Price5);
						}
						else {
							if (lastitinwork5 < fMinXShow) {
								double fp = (fMinXShow - lastitinwork5) * (it->m_Price5 - itLast5->m_Price5) / (i - lastitinwork5) + itLast5->m_Price5;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							m_dMinY = min(m_dMinY, it->m_Price5);
							m_dMaxY = max(m_dMaxY, it->m_Price5);
						}
						itLast5 = it;
						lastitinwork5 = i;
					}
				}
				else {
					if (!bEnd1 && it->m_Price1 > 0) {
						if (itLast1 == pDataKLine->m_List.end()) {
							m_dMinY = min(m_dMinY, it->m_Price1);
							m_dMaxY = max(m_dMaxY, it->m_Price1);
						}
						else {
							if (lastitinwork1 < fMinXShow) {
								double fp = (it->m_Price1 - itLast1->m_Price1) * (fMinXShow - lastitinwork1) / (i - lastitinwork1) + itLast1->m_Price1;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							double fp = (it->m_Price1 - itLast1->m_Price1) * (fMaxXShow - lastitinwork1) / (i - lastitinwork1) + itLast1->m_Price1;
							m_dMinY = min(m_dMinY, fp);
							m_dMaxY = max(m_dMaxY, fp);
						}
						bEnd1 = true;
					}
					if (!bEnd2 && it->m_Price2 > 0) {
						if (itLast2 == pDataKLine->m_List.end()) {
							m_dMinY = min(m_dMinY, it->m_Price2);
							m_dMaxY = max(m_dMaxY, it->m_Price2);
						}
						else {
							if (lastitinwork2 < fMinXShow) {
								double fp = (it->m_Price2 - itLast2->m_Price2) * (fMinXShow - lastitinwork2) / (i - lastitinwork2) + itLast2->m_Price2;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							double fp = (it->m_Price2 - itLast2->m_Price2) * (fMaxXShow - lastitinwork2) / (i - lastitinwork2) + itLast2->m_Price2;
							m_dMinY = min(m_dMinY, fp);
							m_dMaxY = max(m_dMaxY, fp);
						}
						bEnd2 = true;
					}
					if (!bEnd3 && it->m_Price3 > 0) {
						if (itLast3 == pDataKLine->m_List.end()) {
							m_dMinY = min(m_dMinY, it->m_Price3);
							m_dMaxY = max(m_dMaxY, it->m_Price3);
						}
						else {
							if (lastitinwork3 < fMinXShow) {
								double fp = (it->m_Price3 - itLast3->m_Price3) * (fMinXShow - lastitinwork3) / (i - lastitinwork3) + itLast3->m_Price3;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							double fp = (it->m_Price3 - itLast3->m_Price3) * (fMaxXShow - lastitinwork3) / (i - lastitinwork3) + itLast3->m_Price3;
							m_dMinY = min(m_dMinY, fp);
							m_dMaxY = max(m_dMaxY, fp);
						}
						bEnd3 = true;
					}
					if (!bEnd4 && it->m_Price4 > 0) {
						if (itLast4 == pDataKLine->m_List.end()) {
							m_dMinY = min(m_dMinY, it->m_Price4);
							m_dMaxY = max(m_dMaxY, it->m_Price4);
						}
						else {
							if (lastitinwork4 < fMinXShow) {
								double fp = (it->m_Price4 - itLast4->m_Price4) * (fMinXShow - lastitinwork4) / (i - lastitinwork4) + itLast4->m_Price4;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							double fp = (it->m_Price4 - itLast4->m_Price4) * (fMaxXShow - lastitinwork4) / (i - lastitinwork4) + itLast4->m_Price4;
							m_dMinY = min(m_dMinY, fp);
							m_dMaxY = max(m_dMaxY, fp);
						}
						bEnd4 = true;
					}
					if (!bEnd5 && it->m_Price5 > 0) {
						if (itLast5 == pDataKLine->m_List.end()) {
							m_dMinY = min(m_dMinY, it->m_Price5);
							m_dMaxY = max(m_dMaxY, it->m_Price5);
						}
						else {
							if (lastitinwork5 < fMinXShow) {
								double fp = (it->m_Price5 - itLast5->m_Price5) * (fMinXShow - lastitinwork5) / (i - lastitinwork5) + itLast5->m_Price5;
								m_dMinY = min(m_dMinY, fp);
								m_dMaxY = max(m_dMaxY, fp);
							}
							double fp = (it->m_Price5 - itLast5->m_Price5) * (fMaxXShow - lastitinwork5) / (i - lastitinwork5) + itLast5->m_Price5;
							m_dMinY = min(m_dMinY, fp);
							m_dMaxY = max(m_dMaxY, fp);
						}
						bEnd5 = true;
					}
					if (bEnd1 && bEnd2 && bEnd3 && bEnd4 && bEnd5)break;
				}
			}
		}

		if (m_dMinY > 999) { //没有有效数据
			m_dMinY = min_show_def;
			m_dMaxY = max_show_def;
			return;
		}

		if (m_bOptionBond) {
			m_dMinY = (int)(m_dMinY * 4) / 4.0;
			m_dMaxY = (int)(m_dMaxY * 4) / 4.0 + 0.25;
		}
		else {
			m_dMinY = (int)(m_dMinY * 4) / 4.0;
			m_dMaxY = (int)(m_dMaxY * 4) / 4.0 + 0.25;
		}
	}

	int BondQuoteCDCChart::GetKLineIndex(int nIndex, std::list<PriceKLine>::iterator& it) {
		PriceKLineList* pDataKLine = GetPriceKLineList();
		int i = 0;
		std::list<PriceKLine>::iterator itTemp = pDataKLine->m_List.end();
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); it++, i++) {
			if (i == nIndex) {
				return i;
			}
			itTemp = it;
		}
		if (it == pDataKLine->m_List.end() && itTemp != pDataKLine->m_List.end()) {
			it = itTemp;
			return pDataKLine->m_List.size() - 1;
		}
		return -1;
	}

	QString	BondQuoteCDCChart::GetKLineDateString(std::list<PriceKLine>::iterator& it)
	{
		PriceKLineList* pDataKLine = GetPriceKLineList();
		QString szText;
		if (it != pDataKLine->m_List.end()) {
			szText = strInt2DateInTable(it->m_Date);
		}
		return szText;
	}

	QString	BondQuoteCDCChart::strInt2DateInTable(UINT nDate)
	{
		return QString::asprintf("%04d-%02d-%02d", nDate / 10000, (nDate % 10000) / 100, nDate % 100);
	}

	double BondQuoteCDCChart::getXPos_Value(double value)
	{
		QB_CHECK_RETURN_VALUE(bcde, 0);

		if (m_dOriginMaxX - m_dOriginMinX == 0) return 0;
		return (value - m_dOriginMinX) / (m_dOriginMaxX - m_dOriginMinX) * bcde->rect().width();
	}

	void BondQuoteCDCChart::paintEvent(QPaintEvent* event)
	{
		QStylePainter painter(this);

		painter.fillRect(rect(), StyleMgr::instance().color("BasicPlate"));
	}

	void BondQuoteCDCChart::leaveEvent(QEvent* event)
	{
		QB_CHECK_RETURN_VOID1(customPlot);

		customPlot->replot();
	}

	void BondQuoteCDCChart::onMouseMove(QMouseEvent* event)
	{
		QB_CHECK_RETURN_VOID1(customPlot);

		if (m_currentTab == 0)
		{
			if (m_bOptionBond)
			{
				QB_CHECK_RETURN_VOID1(customPlot->graph(0) && customPlot->graph(1) && customPlot->graph(3));
				double dm0 = customPlot->graph(0)->selectTest(event->pos(), false);
				double dm1 = customPlot->graph(1)->selectTest(event->pos(), false);
				double dm3 = customPlot->graph(3)->selectTest(event->pos(), false);
				QColor colorOption(251, 194, 69); //行权收益率
				QColor colorYield(0, 89, 255);   //到期收益率
				QColor colorDeal(124, 84, 195); //成交
				QPen pen(colorOption), penYield(colorYield),penDeal(colorDeal);
				if (0 < dm0 && 2 > dm0)
				{
					pen.setWidth(2);
					customPlot->graph(0)->setPen(pen);

					QColor colorYieldAlpha(colorYield);
					colorYieldAlpha.setAlpha(100);
					penYield.setColor(colorYieldAlpha);
					customPlot->graph(1)->setPen(penYield);
					
					QColor colorDealAlpha(colorDeal);
					colorDealAlpha.setAlpha(100);
					penDeal.setColor(colorDealAlpha);
					customPlot->graph(3)->setPen(penDeal);

				}
				else if (0 < dm1 && 2 > dm1)
				{
					penYield.setWidth(2);
					customPlot->graph(1)->setPen(penYield);

					QColor colorOptionAlpha(colorOption);
					colorOptionAlpha.setAlpha(100);
					pen.setColor(colorOptionAlpha);
					customPlot->graph(0)->setPen(pen);

					QColor colorDealAlpha(colorDeal);
					colorDealAlpha.setAlpha(100);
					penDeal.setColor(colorDealAlpha);
					customPlot->graph(3)->setPen(penDeal);
				}
				else if (0 < dm3 && 2 > dm3)
				{
					penDeal.setWidth(2);
					customPlot->graph(3)->setPen(penDeal);

					QColor penYieldAlpha(colorYield);
					penYieldAlpha.setAlpha(100);
					penYield.setColor(penYieldAlpha);
					customPlot->graph(1)->setPen(penYield);

					QColor colorOptionAlpha(colorOption);
					colorOptionAlpha.setAlpha(100);
					pen.setColor(colorOptionAlpha);
					customPlot->graph(0)->setPen(pen);
				}
				else
				{
					pen.setWidth(1);
					customPlot->graph(0)->setPen(pen);

					penYield.setWidth(1);
					customPlot->graph(1)->setPen(penYield);

					penDeal.setWidth(1);
					customPlot->graph(3)->setPen(penDeal);
				}
			}
			else
			{
				QB_CHECK_RETURN_VOID1(customPlot->graph(0) && customPlot->graph(3));
				double dm0 = customPlot->graph(0)->selectTest(event->pos(), false);
				double dm3 = customPlot->graph(3)->selectTest(event->pos(), false);
				QColor colorYield(205, 119, 4); //估值
				QColor colorDeal(124, 84, 195); //成交
				QPen pen(colorYield), penDeal(colorDeal);
				if (0 < dm0 && 2 > dm0)
				{
					pen.setWidth(2);
					customPlot->graph(0)->setPen(pen);

					QColor colorDealAlpha(colorDeal);
					colorDealAlpha.setAlpha(100);
					penDeal.setColor(colorDealAlpha);
					customPlot->graph(3)->setPen(penDeal);

				}
				else if (0 < dm3 && 2 > dm3)
				{
					penDeal.setWidth(2);
					customPlot->graph(3)->setPen(penDeal);

					QColor colorYieldAlpha(colorYield);
					colorYieldAlpha.setAlpha(100);
					pen.setColor(colorYieldAlpha);
					customPlot->graph(0)->setPen(pen);
				}
				else
				{
					pen.setWidth(1);
					customPlot->graph(0)->setPen(pen);

					penDeal.setWidth(1);
					customPlot->graph(3)->setPen(penDeal);
				}
			}
			/*for (int i = 0; i < 4; i++)
			{
				QB_CHECK_RETURN_VOID1(customPlot->graph(i));
				double dm = customPlot->graph(i)->selectTest(event->pos(), false);
				if (0 < dm && 2 > dm)
				{
					QPen pen = customPlot->graph(i)->pen();
					pen.setWidth(2);
					customPlot->graph(i)->setPen(pen);
				}
				else
				{
					QPen pen = customPlot->graph(i)->pen();
					pen.setWidth(1);
					customPlot->graph(i)->setPen(pen);
				}
			}

			if (m_bOptionBond)
			{
				QB_CHECK_RETURN_VOID1(customPlot->graph(4));
				double dm = customPlot->graph(4)->selectTest(event->pos(), false);
				if (0 < dm && 2 > dm)
				{
					QPen pen = customPlot->graph(4)->pen();
					pen.setWidth(2);
					customPlot->graph(4)->setPen(pen);
				}
				else
				{
					QPen pen = customPlot->graph(4)->pen();
					pen.setWidth(1);
					customPlot->graph(4)->setPen(pen);
				}
			}*/
		}
		else if (m_currentTab == 1)
		{
			QB_CHECK_RETURN_VOID1(customPlot->graph(0) && customPlot->graph(1));

			double dm = customPlot->graph(0)->selectTest(event->pos(), false); //估值
			double dmDeal = customPlot->graph(1)->selectTest(event->pos(), false); //成交
			QColor color(205, 119, 4);  //估值
			QColor colorDeal(124, 84, 195); //成交

			if ((0 < dm && 2 > dm) && (0 < dmDeal && 2 > dmDeal)) 
			{
				QPen pen(color);
				pen.setWidth(2);
				customPlot->graph(0)->setPen(pen);

				QPen penDeal(colorDeal);
				penDeal.setWidth(2);
				customPlot->graph(1)->setPen(penDeal);
			}
			else if (0 < dm && 2 > dm) 
			{
				QPen pen(color);
				pen.setWidth(2);
				customPlot->graph(0)->setPen(pen);

				QPen penDeal;
				QColor cDeal(colorDeal);
				cDeal.setAlpha(100);
				penDeal.setColor(cDeal);
				penDeal.setWidth(1);
				customPlot->graph(1)->setPen(penDeal);
			}
			else if (0 < dmDeal && 2 > dmDeal)
			{
				QPen pen(colorDeal);
				pen.setWidth(2);
				customPlot->graph(1)->setPen(pen);

				QPen penDeal;
				QColor cDeal(color);
				cDeal.setAlpha(100);
				penDeal.setColor(cDeal);
				penDeal.setWidth(1);
				customPlot->graph(0)->setPen(penDeal);
			}
			else
			{
				QPen pen(color);
				pen.setWidth(1);
				customPlot->graph(0)->setPen(pen);


				QPen penDeal(colorDeal);
				penDeal.setWidth(1);
				customPlot->graph(1)->setPen(penDeal);
			}
		}

		customPlot->replot();

		int i_DealType = 0;
		int i = 0;
		std::list<PriceKLine>::iterator it;
		PriceKLineList* pDataKLine = GetPriceKLineList();
		for (it = pDataKLine->m_List.begin(); it != pDataKLine->m_List.end(); ++it, i++) {
			int X = customPlot->xAxis->coordToPixel(i);
			if (abs(event->pos().x() - X) < 3) {
				if (m_nHotPoint != i) {
					m_nHotPoint = i;
				}

				int nLine = 0;
				QString szTip;
				qb::base::CTime T(it->m_Date / 10000, (it->m_Date % 10000) / 100, it->m_Date % 100, 8, 0, 0);
				szTip = QString::asprintf("%d-%02d-%02d", T.GetYear(), T.GetMonth(), T.GetDay());

				if (m_currentTab == 0)
				{
					if (it->m_Price1 > 0) {
						if (m_bOptionBond)
						{
							szTip.append(QString("\n行权收益率(%) %1").arg(it->m_Price1, 0,'f',4,'0'));
						}
						else
						{
							szTip.append(QString("\n估值收益率(%) %1").arg(it->m_Price1, 0, 'f', 4, '0'));
						}

						nLine++;
					}
					if (it->m_Price2 > 0) {
						QString str;
						if (!m_bOptionBond)
						{
							str = QString("\nBid收盘(%) %1").arg(it->m_Price2, 0, 'f', 4, '0');
						}
						if (m_bOptionBond)
						{
							str = QString("\n到期收益率(%) %1").arg(it->m_Price2, 0, 'f', 4, '0');
						}
						szTip.append(str);
						nLine++;
					}
					if (it->m_Price3 > 0) {
						QString str;
						if (!m_bOptionBond)
						{
							str = QString("\nOfr收盘(%) %1").arg(it->m_Price3, 0, 'f', 4, '0');
						}
						if (m_bOptionBond)
						{
							str = QString("\nBid收盘(%) %1").arg(it->m_Price3, 0, 'f', 4, '0');
						}
						szTip.append(str);
						nLine++;
					}

					if (it->m_Price4 > 0) {
						QString str;
						if (!i_DealType)
						{
							str = QString("\n成交日均(%) %1").arg(it->m_Price4, 0, 'f', 4, '0');
						}
						else
						{
							str = QString("\n成交收盘(%) %1").arg(it->m_Price4, 0, 'f', 4, '0');
						}
						szTip.append(str);
						nLine++;
					}
					if (m_bOptionBond)
					{
						if (it->m_Price5 > 0) {
							szTip.append(QString("\nOfr收盘(%) %1").arg(it->m_Price5, 0, 'f', 4, '0'));
							nLine++;
						}
					}
				}
				else if (m_currentTab == 1)
				{
					if (it->m_Price4 > 0) {
						QString str;
						if (!i_DealType)
						{
							str = QString("\n成交日均(元) %1").arg(it->m_Price4, 0, 'f', 4, '0');
						}
						else
						{
							str = QString("\n成交收盘(元) %1").arg(it->m_Price4, 0, 'f', 4, '0');
						}
						szTip.append(str);
						nLine++;
					}
					if (it->m_Price2 > 0) {
						szTip.append(QString("\n估值净价(元) %1").arg(it->m_Price2, 0, 'f', 4, '0'));
						nLine++;
					}
				}

				//补充其他几种情况
				if (szTip.length() > 0) {
					std::vector<QBTipCustomItem> vctCustomItem;
					QBTipCustomItem item;
					item.clrNormal = QColor(223, 174, 76, 255);
					item.col = 1;

					for (i = 0; i < nLine; i++)
					{
						item.row = i+1;
						vctCustomItem.push_back(item);
					}

					QBTips::showText(event->screenPos().toPoint(), szTip, this, &vctCustomItem);
				}
				return;
			}
		}

		if (m_nHotPoint >= 0) {
			m_nHotPoint = -1;
			QBTips::hideTip();
		}
	}
}
